home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dmake / run.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  6KB  |  301 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  RUN.C
  9.  */
  10.  
  11. #include "defs.h"
  12. #ifdef AMIGA
  13. #include <dos/dosextens.h>
  14. #include <dos/var.h>
  15. #include <dos/dostags.h>
  16. #else
  17. #include <unistd.h>
  18. #include <sys/wait.h>
  19. #endif
  20.  
  21. typedef struct CommandLineInterface CLI;
  22. typedef struct Process            Process;
  23.  
  24. Prototype long Execute_Command(char *, short);
  25. Prototype void InitCommand(void);
  26. Prototype long LoadSegLock(long, char *);
  27.  
  28. #ifdef AMIGA
  29. BPTR SaveLock;
  30. #endif
  31. char RootPath[512];
  32.  
  33. extern struct Library *SysBase;
  34.  
  35. void
  36. ICExit(void)
  37. {
  38. #ifdef AMIGA
  39.     if (SaveLock) {
  40.     UnLock(CurrentDir(SaveLock));
  41.     SaveLock = NULL;
  42.     }
  43. #endif
  44. }
  45.  
  46. void
  47. InitCommand()
  48. {
  49. #ifdef AMIGA
  50.     SaveLock = CurrentDir(DupLock(((Process *)FindTask(NULL))->pr_CurrentDir));
  51. #endif
  52.     getcwd(RootPath, sizeof(RootPath));
  53.     atexit(ICExit);
  54. }
  55.  
  56. /*
  57.  *  cmd[-1] is valid space and, in fact, must be long word aligned!
  58.  */
  59.  
  60. long
  61. Execute_Command(char *cmd, short ignore)
  62. {
  63.     register char *ptr;
  64.  
  65.     for (ptr = cmd; *ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '\n'; ++ptr)
  66.     ;
  67.  
  68.  
  69.     /*
  70.      *    Internal MakeDir because AmigaDOS 2.04's MakeDir is unreliable
  71.      *    with RunCommand() (it can crash)
  72.      *
  73.      *    Internal CD because we special case it
  74.      */
  75.  
  76. #ifdef AMIGA
  77.     if (ptr - cmd == 7 && strnicmp(cmd, "makedir", 7) == 0) {
  78.     long lock;
  79.     short err = 0;
  80.  
  81.     while (*ptr == ' ' || *ptr == '\t')
  82.         ++ptr;
  83.     if (lock = CreateDir(ptr))
  84.         UnLock(lock);
  85.     else {
  86.         printf("Unable to makedir %s\n", ptr);
  87.         err = 20;
  88.     }
  89.     return((ignore) ? 0 : err);
  90.     } else
  91.     if (ptr - cmd == 6 && strnicmp(cmd, "fwrite", 6) == 0) {
  92.     char *t;
  93.     BPTR fh;
  94.     short err = 0;
  95.  
  96.     while (*ptr == ' ' || *ptr == '\t')
  97.         ++ptr;
  98.     for (t = ptr; *t && *t != ' ' && *t != '\t'; t++);
  99.     if (*t) *t++ = '\0';
  100.     if (fh = Open(ptr, MODE_NEWFILE)) {
  101.         int len;
  102.         len = strlen(t);
  103.         for(ptr = t; *ptr; ptr++) if (*ptr == ' ') *ptr = '\n';
  104.         t[len] = '\n';
  105.         Write(fh, t, len+1);
  106.         t[len] = '\0';
  107.         Close(fh);
  108.         err = 0;
  109.     }
  110.     else
  111.     {
  112.         printf("Unable to write %s\n", ptr);
  113.         err = 20;
  114.     }
  115.        return((ignore) ? 0 : err);
  116.     } else
  117. #endif
  118.     if (ptr - cmd == 2 && strncasecmp(cmd, "cd", 2) == 0) {
  119. #ifdef AMIGA
  120.     long lock;
  121. #endif
  122.     short err = 0;
  123.  
  124.     while (*ptr == ' ' || *ptr == '\t')
  125.         ++ptr;
  126.     {
  127.         short len = strlen(ptr);    /*  XXX HACK HACK */
  128.         if (len && ptr[len-1] == '\n')
  129.         ptr[len-1] = 0;
  130.     }
  131. #ifdef AMIGA
  132.     if (*ptr == 0)
  133.         lock = DupLock(SaveLock);
  134.     else
  135.         lock = Lock(ptr, SHARED_LOCK);
  136.     if (lock)
  137.         UnLock(CurrentDir(lock));
  138.     else {
  139.         printf("Unable to cd %s\n", ptr);
  140.         err = 20;
  141.     }
  142. #else
  143.     if (*ptr == 0)
  144.         err = chdir(RootPath);
  145.     else
  146.         err = chdir(ptr);
  147.     if (err != 0) {
  148.         err = 20;
  149.         printf("Unable to cd %s\n", ptr);
  150.     }
  151. #endif
  152.     return((ignore) ? 0 : err);
  153.     }
  154.  
  155.     /*
  156.      * run command cmd
  157.      *
  158.      */
  159.  
  160. #ifdef AMIGA
  161.     {
  162.     short i;
  163.     short ci;
  164.     short c;
  165.     short err = 0;
  166.     short useSystem = 0;
  167.     Process *proc = (Process *)FindTask(NULL);
  168.     char *cmdArgs;
  169.  
  170.     for (i = 0; cmd[i] && cmd[i] != ' ' && cmd[i] != 9 && cmd[i] != 10 && cmd[i] != 13; ++i)
  171.         ;
  172.     if (strpbrk(cmd + i, "<>|`"))
  173.         useSystem = 1;
  174.     else
  175.         useSystem = 0;
  176.  
  177.     if (c = cmd[ci = i])
  178.         ++ci;
  179.     cmd[i] = 0;
  180.  
  181.     cmdArgs = malloc(strlen(cmd + ci) + 3);
  182.     sprintf(cmdArgs, "%s\n\r", cmd + ci);
  183.     fflush(stdout);
  184.  
  185.     /*
  186.      *  NOTE: RunCommand() is unreliable if no pr_CLI exists,
  187.      *  MUST use system13() in that case.
  188.      */
  189.  
  190. #if INCLUDE_VERSION >= 36
  191.     if (SysBase->lib_Version >= 36 && proc->pr_CLI) {
  192.         long seg;
  193.         long stack;
  194.         long lock = 0;
  195.         CLI *cli = (CLI *)BADDR(proc->pr_CLI);
  196.         static char OldCmd[128];
  197.         char dt[4];
  198.         struct TagItem *tags[] = {
  199.         NP_CopyVars, TRUE,
  200.         TAG_END, NULL};
  201.  
  202.         if (cli) {
  203.         GetProgramName(OldCmd, sizeof(OldCmd));
  204.         SetProgramName(cmd);
  205.         stack = cli->cli_DefaultStack * 4;
  206.         } else {
  207.         stack = 8192;
  208.         }
  209.  
  210.         /*
  211.          *    note: Running2_04() means V37 or greater
  212.          */
  213.  
  214.         if (useSystem || (Running2_04() && GetVar(cmd, dt, 2, LV_ALIAS | GVF_LOCAL_ONLY) >= 0))
  215.         goto dosys;
  216.  
  217.         if ((seg = FindSegment(cmd, 0L, 0)) || (seg = FindSegment(cmd, 0L, 1))) {
  218.         dbprintf(("A cmd = '%s' stack = %d\n", cmdArgs, stack));
  219.         err = RunCommand(((long *)seg)[2], stack, cmdArgs, strlen(cmdArgs) - 1);
  220.         } else if ((lock = _SearchPath(cmd)) && (seg = LoadSegLock(lock, ""))) {
  221.         dbprintf(("B\n"));
  222.         err = RunCommand(seg, stack, cmdArgs, strlen(cmdArgs) - 1);
  223.         UnLoadSeg(seg);
  224.         } else if ((lock = Lock("dcc:bin", SHARED_LOCK)) && (seg = LoadSegLock(lock, cmd))) {
  225.         dbprintf(("C %08x\n", seg));
  226.         dbprintf(("CMD= %s", cmdArgs));
  227.         err = RunCommand(seg, 8192, cmdArgs, strlen(cmdArgs) - 1);
  228.         UnLoadSeg(seg);
  229.         } else {
  230. dosys:
  231.         dbprintf(("D\n"));
  232.         cmd[i] = c;
  233.         /*err = system13(cmd);*/
  234.         err = SystemTagList(cmd, tags);
  235.         }
  236.         if (cli)
  237.         SetProgramName(OldCmd);
  238.         if (lock)
  239.         UnLock(lock);
  240.     } else
  241. #endif
  242.     {
  243.         dbprintf(("E\n"));
  244.         cmd[i] = c;
  245.         err = system13(cmd);
  246.     }
  247.     free(cmdArgs);
  248.     if (err)
  249.         printf("Exit code %d %s\n", err, (ignore) ? "(Ignored)":"");
  250.     if (ignore)
  251.         return(0);
  252.     return(err);
  253.     }
  254. #else
  255.     {
  256.     int err;
  257.  
  258.     if ((err = vfork()) == 0) {
  259.         execlp("/bin/sh", "/bin/sh", "-c", cmd, 0);
  260.         exit(30);
  261.     } else {
  262. #ifdef NOTDEF
  263.         union wait uwait;
  264.  
  265.         while (wait(&uwait) != err || WIFEXITED(uwait) == 0)
  266.         ;
  267.         err = uwait.w_retcode;
  268. #endif
  269.         int status;
  270.         while (wait(&status) != err || WIFEXITED(status) == 0)
  271.         ;
  272.         err = WEXITSTATUS(status);
  273.     }
  274.     if (err)
  275.         printf("Exit code %d %s\n", err, (ignore) ? "(Ignored)":"");
  276.     if (ignore)
  277.         return(0);
  278.     return(err);
  279.     }
  280. #endif
  281. }
  282.  
  283. #ifdef AMIGA
  284.  
  285. long
  286. LoadSegLock(lock, cmd)
  287. long lock;
  288. char *cmd;
  289. {
  290.     long oldLock;
  291.     long seg;
  292.  
  293.     oldLock = CurrentDir(lock);
  294.     seg = LoadSeg(cmd);
  295.     CurrentDir(oldLock);
  296.     return(seg);
  297. }
  298.  
  299.  
  300. #endif
  301.